package com.okcl.controller;

import cn.hutool.json.JSONUtil;
import com.okcl.dto.LoginDto;
import com.okcl.dto.Result;
import com.okcl.entity.User;
import com.okcl.mapper.UserMapper;
import com.okcl.security.LoginUserDetails;
import com.okcl.utils.JwtUtils;
import com.okcl.utils.RedisClient;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {
    @Resource
    private RedisClient redisClient;
    @Resource
    private UserMapper userMapper;
    @Resource
    private AuthenticationManager authenticationManager;

    @PostMapping("/login")
    public Result login(@RequestBody LoginDto loginDto, HttpServletRequest request) {
        //判断是否已经登录
        String headerToken = request.getHeader("token");
        if (StringUtils.hasText(headerToken)) {
            //登陆过
            String claim = JwtUtils.getClaim(headerToken);
            if (StringUtils.hasText(claim) && claim.equals(loginDto.getUsername()) && JwtUtils.verify(headerToken)) {
                String key = "login:token:" + headerToken;
                redisClient.del(key);
            }
        }
        //封装用户名和密码
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword());
        //调用认证方法
        try {
            Authentication authenticate = authenticationManager.authenticate(token);
            if (ObjectUtils.isEmpty(authenticate)) {
                throw new RuntimeException("用户名或密码错误");
            }
            //生成token
            String jwt = JwtUtils.sign(loginDto.getUsername(), 1000 * 60 * 60 * 24 * 7L);
            String key = "login:token:" + jwt;
            LoginUserDetails principal = (LoginUserDetails) authenticate.getPrincipal();
            String jsonStr = JSONUtil.toJsonStr(principal);
            Map<String, String> map = new HashMap<>();
            redisClient.set(key, jsonStr, 1000 * 6 * 6 * 60L);
            map.put("token", jwt);
            boolean verify = JwtUtils.verify(jwt);
            log.info("解析成功 verify:{} ", verify);
            log.info("载体 :{}", JwtUtils.getClaim(jwt));
            return Result.ok(map);
        } catch (AuthenticationException e) {
            throw new RuntimeException("用户名或密码错误");
        }
    }

    @GetMapping("/getUser")
    public Result getUser(@RequestParam(value = "username", required = false) String username) {
        User user = userMapper.getUserByUsername(username);
        return Result.ok(user);
    }
}
